﻿using Furion;
using System;
using System.Reflection;
using YFurion.Extensions;
using YFurion.Session;
using YFurion.Utils;

namespace YFurion.Entities.Extensions
{
    public static class EntityExtensions
    {
        public static string GetTableName(this Type entityType)
        {
            IYSession ySession = App.GetService<IYSession>();
            string entityName = entityType.Name;
            string tableName = entityName + (ySession.TableSuffixDictionary.ContainsKey(entityName) ? ySession.TableSuffixDictionary[entityName] : DateTime.Now.Year.ToString());
            return tableName;
        }

        public static string GetTableName(this Type entityType, string tableSuffix)
        {
            string tableName = entityType.Name + tableSuffix ?? string.Empty;
            return tableName;
        }

        public static void SetIdProperty(this object entityAsObj)
        {
            Type type = entityAsObj.GetType();
            PropertyInfo propertyInfo = type.GetProperty(nameof(IYEntity.Id), BindingFlags.Public | BindingFlags.Instance);
            if (propertyInfo != null)
            {
                object value = propertyInfo.GetValue(entityAsObj);
                if (propertyInfo.PropertyType.Name.Equals("Int64") && Convert.ToInt64(value) <= 0)
                {
                    propertyInfo.SetValue(entityAsObj, YIDGenerator.NextId());
                }
            }
        }

        /// <summary>
        /// 设置创建属性
        /// </summary>
        /// <param name="entityAsObj"></param>
        /// <param name="userId"></param>
        public static void SetCreationProperties(this object entityAsObj, long userId)
        {
            entityAsObj.SetIdProperty();

            if (entityAsObj is IHasCreationTime)
            {
                IHasCreationTime entity = entityAsObj.As<IHasCreationTime>();

                if (entity.CreationTime == default(DateTime))
                {
                    entity.CreationTime = DateTime.Now;
                }
            }

            if (entityAsObj is ICreationAudited)
            {
                ICreationAudited entity = entityAsObj.As<ICreationAudited>();

                if (userId <= 0)
                {
                    return;
                }

                if (entity.CreatorUserId > 0)
                {
                    return;
                }

                entity.CreatorUserId = userId;
            }
        }


        /// <summary>
        /// 设置修改属性
        /// </summary>
        /// <param name="entityAsObj"></param>
        /// <param name="userId"></param>
        public static void SetModificationProperties(this object entityAsObj, long userId)
        {
            if (entityAsObj is IHasModificationTime)
            {
                IHasModificationTime entity = entityAsObj.As<IHasModificationTime>();

                entity.LastModificationTime = DateTime.Now;
            }

            if (entityAsObj is IModificationAudited)
            {
                IModificationAudited entity = entityAsObj.As<IModificationAudited>();

                if (userId <= 0)
                {
                    entity.LastModifierUserId = 0;
                    return;
                }

                entity.LastModifierUserId = userId;
            }
        }

        /// <summary>
        /// 是否软删除
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public static bool IsSoftDelete(this object entityAsObj)
        {
            return entityAsObj.IsSoftDeleteObj() && entityAsObj.As<ISoftDelete>().IsDeleted;
        }

        /// <summary>
        /// 是否是软删除对象
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public static bool IsSoftDeleteObj(this object entityAsObj)
        {
            return entityAsObj is ISoftDelete;
        }

        /// <summary>
        /// 设置假删除属性
        /// </summary>
        /// <param name="entityAsObj"></param>
        /// <param name="userId"></param>
        public static void SetDeletionProperties(this object entityAsObj, long userId)
        {
            if (entityAsObj is ISoftDelete)
            {
                ISoftDelete entity = entityAsObj.As<ISoftDelete>();
                entity.IsDeleted = true;
            }

            if (entityAsObj is IHasDeletionTime)
            {
                IHasDeletionTime entity = entityAsObj.As<IHasDeletionTime>();

                entity.DeletionTime = DateTime.Now;
            }

            if (entityAsObj is IDeletionAudited)
            {
                IDeletionAudited entity = entityAsObj.As<IDeletionAudited>();

                if (userId <= 0)
                {
                    entity.DeleterUserId = 0;
                    return;
                }

                entity.DeleterUserId = userId;
            }
        }
    }
}
